package eop.graham

import java.util.Map;
import groovy.util.GroovyTestCase
//import org.apache.log4j.*

class LoadDataFromTsvFileService {

	Data Data

	static List BRAIN_REGIONS = ["POm", "VL", "VP", "LM"]
	static List STAT_METHODS = ["RMA", "MAS5"]

	static String FIELD_SEPARATOR = "\t"

	static Map COLUMN_NAME = [
		1:"Mouse430_2.na31.annot::Gene Symbol",
		2:"Gene_Aliases",
		3:"Affy table::Gene_Description",
		4:"Comments",
		5:"Last Modified",
		6:"Last Modified By",
		7:"plan",
		8:"Probe",
		9:"probe design",
		10:"RANKLGVL",
		11:"RANKPOMVL",
		12:"RANKVPLGN",
		13:"RANKVPPOm",
		14:"RANKVPVL",
		15:"_All_DEVABA_from_JohnHohman_ Sheet1::Gene symbol",
		16:"Affy table::Gene_Symbol",
		17:"bgemDataAllGenes 2::probeName",
		18:"genepaint thalamus specific::genepaint",
		19:"MAS5allreplicates::fold LGP3P10",
		20:"MAS5allreplicates::fold POmP0P10",
		21:"MAS5allreplicates::fold POmP0P3",
		22:"MAS5allreplicates::fold POmP3P10",
		23:"MAS5allreplicates::fold VLP0P10",
		24:"MAS5allreplicates::fold VLP0P3",
		25:"MAS5allreplicates::fold VLP3P10",
		26:"MAS5allreplicates::fold VPP0P10",
		27:"MAS5allreplicates::fold VPP0P3",
		28:"Mouse430_2.na30.annot::Gene Symbol",
		29:"Mouse430_2.na31.annot::Gene Ontology Biological Process",
		30:"Mouse430_2.na31.annot::Gene Ontology Cellular Component",
		31:"Mouse430_2.na31.annot::Gene Ontology Molecular Function",
		32:"POm MAS5 intensities::Mean reference",
		33:"VP MAS5 intensities::VPP0Mean experience",
		34:"VPPOm::MAS5 minus sign P0",
		35:"VPPOm::MAS5 P0 Fold change",
		36:"VPPOm::MAS5 P0 Pvalue",
		37:"VPPOm::MAS5 P10 Fold change",
		38:"VPPOm::MAS5 P10 Pvalue",
		39:"VPPOm::MAS5 P3 Fold change",
		40:"VPPOm::MAS5 P3 Pvalue",
		41:"VPPOm::RMA P0 Fold change",
		42:"VPPOm::RMA P0 Pvalue",
		43:"VPPOm::RMA P10 Fold change",
		44:"VPPOm::RMA P3 Fold change",
		45:"VPPOm::RMA P3 Pvalue",
	]

	static String GENE_NAME = COLUMN_NAME[1]
	static String OWNER_NAME = COLUMN_NAME[6]
	static String PROBE_NAME = COLUMN_NAME[8]
	static String POM = "POm"
	static String VP = "VP"
	static String MAS5 = "MAS5"
	static String POM_INTENSITY = COLUMN_NAME[32]
	static String POM_FC_P3 = COLUMN_NAME[21]
	static String POM_FC_P10 = COLUMN_NAME[20]
	static String VP_INTENSITY = COLUMN_NAME[33]
	static String VP_FC_P3 = COLUMN_NAME[27]
	static String VP_FC_P10 = COLUMN_NAME[26]

	static transactional = true

	int linesProcessed = 0	// counts input file lines
	int successes = 0	// counts successful additions to database
	List failures = []	// notes problem input file line numbers
	
	def loadDataFromTsvFile(String tsvFileName) {

		File tsvFile = new File(tsvFileName)

		tsvFile.splitEachLine(FIELD_SEPARATOR){ oneGeneRawData ->
			linesProcessed++
			checkEnoughFields(oneGeneRawData)
			oneGeneRawData = makeWellFormed(oneGeneRawData)
			//println oneGeneRawData
			Map oneGene = rawDataToMap(oneGeneRawData)
			addToDatabase(oneGene)
		}
		println "Lines Processed: ${linesProcessed}"
		println "Successful additions: ${successes}"
		println "Problem input file line numbers as follows: $failures"
		return failures
	}

	Void checkEnoughFields(List dataFields) {
		if (dataFields.size() < COLUMN_NAME.size()){
			groovy.util.GroovyTestCase.log.info "Warning: too few fields in record ${dataFields}"
			//log.info "Warning: too few fields in record ${dataFields}"
			//println "Warning: too few fields in record ${dataFields}"
		}
	}

	List makeWellFormed(List dataFields) {
		// replace vertical tabs within data fields with spaces
		dataFields = dataFields.collect{it.replaceAll(/\v/," ")}
		return dataFields
	}

	Map rawDataToMap(List dataFields) {
		Map dataMap = [:]

		dataFields.eachWithIndex{ field, index ->
			dataMap << [(COLUMN_NAME[index+1]):field]
		}

		return dataMap
	}

	def addToDatabase(Map oneGene) {

		String oneGeneName = oneGene[GENE_NAME]
		String oneOwner = oneGene[OWNER_NAME]
		String oneProbe = oneGene[PROBE_NAME]

		def beanToSave = new Data(
				geneName:oneGeneName,
				statMethod:MAS5,
				POmIntensity:oneGene[POM_INTENSITY] as BigDecimal,
				POmFoldChangeP3:oneGene[POM_FC_P3] as BigDecimal,
				POmFoldChangeP10:oneGene[POM_FC_P10] as BigDecimal,
				VPIntensity:oneGene[VP_INTENSITY] as BigDecimal,
				VPFoldChangeP3:oneGene[VP_FC_P3] as BigDecimal,
				VPFoldChangeP10:oneGene[VP_FC_P10] as BigDecimal,
				probe:oneProbe,
				//owner:owner,
				)

		//def saveResult

		//println "Intensity is ${beanToSave.POmIntensity}"
		//groovy.util.GroovyTestCase.log.info
		//println "About to save ${beanToSave.geneName}"
		try{beanToSave.save(failOnError: true)
			successes++
		}catch(Exception e){
			failures << linesProcessed
			println "Exception saving ${beanToSave.geneName}: ${e}"
		}
		//println "saveResult was ${saveResult}"
		//def saveResult = beanToSave.save()
		//return saveResult


	}
}